package com.scau.bookstore.api.controller;

import com.scau.bookstore.api.annotation.LoginAuthToken;
import com.scau.bookstore.api.exception.NoEnoughStockException;
import com.scau.bookstore.api.util.JwtUtil;
import com.scau.bookstore.common.entity.*;
import com.scau.bookstore.common.pojo.*;
import com.scau.bookstore.contract.service.*;
import com.scau.bookstore.repository.mapper.OrderItemDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.util.*;


@RestController
@CrossOrigin
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private BookService bookService;

    @Autowired
    private ReviewService reviewService;

    @Autowired
    private AddressService addressService;

    @Autowired
    private OrderItemDao orderItemDao;

    /**
     * 创建订单
     */
    @LoginAuthToken
    @Transactional
    @PostMapping("/addOrder")
    public Result addOrder(@RequestBody OrderForm orderForm, HttpServletRequest request) {
        String token = request.getHeader("X-Token");
        Long userId = JwtUtil.getIdByToken(token);
        List<CartItem> cartItems = orderForm.getCartItems();
        Order order = Order.builder().userId(userId)
                .addressId(orderForm.getAddressId()).userMessage(orderForm.getComment()).build();
        orderService.add(order);
        for (CartItem cartItem : cartItems) {
            Book book = bookService.findById(cartItem.getId());
            if (book.getStock() < cartItem.getNumber()) {
                throw new NoEnoughStockException("库存不足");
            }
            book.setStock(book.getStock() - cartItem.getNumber());
            book.setSaleNumber(book.getSaleNumber() + cartItem.getNumber());
            OrderItem orderItem = OrderItem.builder().orderId(order.getId())
                    .bookId(cartItem.getId()).number(cartItem.getNumber()).build();
            orderItemDao.save(orderItem);
        }
        return new Result(true, StatusCode.OK, "下单成功", order.getId());
    }

	/**
	 * 订单支付
	 * @param id
	 * @return
	 */
	@LoginAuthToken
	@GetMapping(value = "/pay/{id}")
    public Result pay(@PathVariable Long id) {
    	Order order = orderService.findById(id);
    	if (null == order) {
    		return new Result(false, StatusCode.ERROR, "订单不存在");
		}
    	order.setStatus((byte) 2);
    	order.setPayDate(new Date());
		orderService.update(order);
        return new Result(true, StatusCode.OK, "支付成功");
    }

    /**
     * 发货
     * @param id
     * @return
     */
    @LoginAuthToken
    @GetMapping(value = "/send/{id}")
    public Result send(@PathVariable Long id) {
        Order order = orderService.findById(id);
        if (null == order) {
            return new Result(false, StatusCode.ERROR, "订单不存在");
        }
        order.setStatus((byte) 3);
        order.setDeliveryDate(new Date());
        orderService.update(order);
        return new Result(true, StatusCode.OK, "确认成功");
    }

    /**
     * 确认收货
     * @param id
     * @return
     */
    @LoginAuthToken
    @GetMapping(value = "/confirm/{id}")
    public Result confirm(@PathVariable Long id) {
        Order order = orderService.findById(id);
        if (null == order) {
            return new Result(false, StatusCode.ERROR, "订单不存在");
        }
        order.setStatus((byte) 4);
        order.setConfirmDate(new Date());
        orderService.update(order);
        return new Result(true, StatusCode.OK, "确认成功");
    }

    /**
     * 评价订单
     */
    @LoginAuthToken
    @PostMapping(value = "/comment/{id}")
    public Result comment(@PathVariable Long id, @RequestBody CommentForm commentForm, HttpServletRequest request) {
        Order order = orderService.findById(id);
        String token = request.getHeader("X-Token");
        Long userId = JwtUtil.getIdByToken(token);
        Set<OrderItem> orderItems = order.getOrderItems();
        for (OrderItem orderItem: orderItems) {
            Review review = Review.builder().bookId(orderItem.getBookId()).userId(userId)
                    .content(commentForm.getComment()).build();
            reviewService.add(review);
        }
        order.setStatus((byte) 5);
        orderService.update(order);
        return new Result(true, StatusCode.OK, "评价成功");
    }

	/**
	 * 查询个人订单
	 */
	@LoginAuthToken
	@GetMapping("/getOrderList")
	public Result findByUserId(HttpServletRequest request) {
        String token = request.getHeader("X-Token");
        Long userId = JwtUtil.getIdByToken(token);
		Map map = new HashMap();
		map.put("userId", userId);
        List<Order> orderList = orderService.findSearch(map);
        for (Order order: orderList) {
            Address address = addressService.findById(order.getAddressId());
            order.setAddress(address);
            for (OrderItem orderItem: order.getOrderItems()) {
                orderItem.setBook(bookService.findById(orderItem.getBookId()));
            }
        }
		return new Result(true, StatusCode.OK, "查询成功", orderList);
	}

    /**
     * 获取订单地址信息
     */
    @LoginAuthToken
    @GetMapping("/getOrderAddress/{id}")
    public Result getOrderAddress(@PathVariable Long id) {
        Order order = orderService.findById(id);
        Address address = addressService.findById(order.getAddressId());
        order.setAddress(address);
        return new Result(true, StatusCode.OK, "查询成功", address);
    }

	/**
     * 查询全部数据
     *
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public Result findAll() {
        return new Result(true, StatusCode.OK, "查询成功", orderService.findAll());
    }

    /**
     * 根据ID查询
     *
     * @param id ID
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Result findById(@PathVariable Long id) {
        return new Result(true, StatusCode.OK, "查询成功", orderService.findById(id));
    }


    /**
     * 分页+多条件查询
     *
     * @param searchMap 查询条件封装
     * @param page      页码
     * @param size      页大小
     * @return 分页结果
     */
    @RequestMapping(value = "/search/{page}/{size}", method = RequestMethod.POST)
    public Result findSearch(@RequestBody Map searchMap, @PathVariable int page, @PathVariable int size) {
        Page<Order> orderList = orderService.findSearch(searchMap, page, size);
        for (Order order: orderList) {
            Address address = addressService.findById(order.getAddressId());
            order.setAddress(address);
            for (OrderItem orderItem: order.getOrderItems()) {
                orderItem.setBook(bookService.findById(orderItem.getBookId()));
            }
        }
        return new Result(true, StatusCode.OK, "查询成功", new PageResult<Order>(orderList.getTotalElements(), orderList.getContent()));
    }

    /**
     * 根据条件查询
     *
     * @param searchMap
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public Result findSearch(@RequestBody Map searchMap) {
        return new Result(true, StatusCode.OK, "查询成功", orderService.findSearch(searchMap));
    }

    /**
     * 增加
     *
     * @param order
     */
    @RequestMapping(method = RequestMethod.POST)
    public Result add(@RequestBody Order order) {
        orderService.add(order);
        return new Result(true, StatusCode.OK, "增加成功");
    }

    /**
     * 修改
     *
     * @param order
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public Result update(@RequestBody Order order, @PathVariable Long id) {
        order.setId(id);
        orderService.update(order);
        return new Result(true, StatusCode.OK, "修改成功");
    }

    /**
     * 删除
     *
     * @param id
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public Result delete(@PathVariable Long id) {
        orderService.deleteById(id);
        return new Result(true, StatusCode.OK, "删除成功");
    }

}
